#include "StdAfx.h"
#include "GWMsgMan.h"

GWMsgMan::GWMsgMan(void)
{
}

GWMsgMan::~GWMsgMan(void)
{
}


VOID GWMsgMan::InitConfig()
{
	char chFileName[MAX_PATH] = {0};
	sprintf(chFileName,".\\gw_cfg.ini");

	m_nPort  = ::GetPrivateProfileInt(_T("GW_SVR"),_T("port"),13000, chFileName);
}

int GWMsgMan::GWStart()
{
	GWListenThread::SetConnectTime(5000,100);
	GWListenThread::SetPort( m_nPort );

	return GWListenThread::Start();
}

int GWMsgMan::GWStop()
{
	return GWListenThread::Stop(); 
}



int GWMsgMan::vTcpCmdDispatch(SOCKET hClientSocket,NET_PACKET_HEAD *pMsgHead,BYTE *pBuffer)
{
	int nRet = TG_ERR_FAILURE;

	int  nRetSize = sizeof(NET_PACKET_HEAD);
	char szRetBuffer[256];
	memset(szRetBuffer,0,sizeof(szRetBuffer));

	NET_PACKET_HEAD *pRetMsgHead = (NET_PACKET_HEAD*)szRetBuffer;

	pRetMsgHead->nMsgType   = pMsgHead->nMsgType + 1;
	pRetMsgHead->nFrameSize = 0;
	pRetMsgHead->nDataLen   = 0;

	SOCKADDR_IN addrPeer;
	int nAddrLen = sizeof(addrPeer);
	getpeername(hClientSocket, (PSOCKADDR) &addrPeer, &nAddrLen);

	char szPeerIP[128] = { 0 };
	sprintf(szPeerIP, "%s", inet_ntoa(addrPeer.sin_addr));
	int nPeerPort = ntohs(addrPeer.sin_port);

	switch( pMsgHead->nMsgType )
	{
	case ping_gw_req:
		{
			if( pMsgHead->nDataLen == sizeof(TcsPingGW) )
			{
				TcsPingGW *pTcs = (TcsPingGW*)pBuffer;

				UpdateCsInfo( pTcs,szPeerIP,nPeerPort );

				memcpy( szRetBuffer+sizeof(NET_PACKET_HEAD),pTcs->nodeid,sizeof(pTcs->nodeid) );

				pRetMsgHead->nFrameSize = 12;
				pRetMsgHead->nDataLen   = 12;

				nRetSize += 12;

				nRet = TG_ERR_SUCCESS;
			}
		}
		break;
	case get_tcs_req:
		{
			if( pRetMsgHead->nDataLen == sizeof(ReqTcsInfo) )
			{
				ReqTcsInfo *pReq = (ReqTcsInfo*)pBuffer;

				int nSelect = 0;

				for(int i=0;i<32;i++)
				{
                    nSelect += pReq->LoginName[i];
				}

				RetTcsInfo *pTcsInfo = (RetTcsInfo *)(szRetBuffer + sizeof(NET_PACKET_HEAD) );

				GetCsInfo(nSelect,pTcsInfo);

				pRetMsgHead->nFrameSize = sizeof(RetTcsInfo);
				pRetMsgHead->nDataLen   = sizeof(RetTcsInfo);
				nRetSize += sizeof(RetTcsInfo);

				nRet = TG_ERR_SUCCESS;
			}
		}
		break;
	default:
		break;
	}

	pRetMsgHead->nErrFlag   = nRet;
	pRetMsgHead->SetCRC();

	DWORD dwRet = 0;
	TGSendDataS(hClientSocket,
		(char*)szRetBuffer,nRetSize,
		&dwRet,
		GWListenThread::m_hWSACmdSREvent,
		GWListenThread::m_hWSAExitEvent,TG_WAITTIME);

	TGShutDownSocket( hClientSocket );
	TGCloseSocket( hClientSocket );
	hClientSocket = NULL;

	return nRet;
}


int GWMsgMan::UpdateCsInfo(TcsPingGW *pTcs,char *pCsIP,int nCsPort)
{
	TG_AUTO_LOCK xLock(&m_Sect);

	int nCount = (int)m_arCsInfo.size();
	for( int i=0;i<nCount;i++ )
	{
        if( ( 0 == memcmp( m_arCsInfo[i].xCsBase.nodeid,pTcs->nodeid,sizeof(pTcs->nodeid) ) )&&
            ( 0 == memcmp( m_arCsInfo[i].xRetCsInfo.csip,pCsIP,32 ) ) &&
            ( m_arCsInfo[i].xRetCsInfo.csport == nCsPort )
		  )
		{
            m_arCsInfo[i].xCsBase = *pTcs;
			memcpy( m_arCsInfo[i].xRetCsInfo.Public_key,pTcs->Public_key,sizeof(pTcs->Public_key) );

			return 0;
		}
	}

	TcsInfo xTcsInfo;
	xTcsInfo.xCsBase          = *pTcs;
	memcpy( xTcsInfo.xRetCsInfo.csip,pCsIP, 32 );
	xTcsInfo.xRetCsInfo.csport = nCsPort;
	memcpy( xTcsInfo.xRetCsInfo.Public_key,pTcs->Public_key,sizeof(pTcs->Public_key) );

	m_arCsInfo.push_back( xTcsInfo );

	return 0;
}

int GWMsgMan::GetCsInfo(int nSelect,RetTcsInfo *pTcsInfo)
{
	TG_AUTO_LOCK xLock(&m_Sect);

	int nCount = (int)m_arCsInfo.size();
	int nIndex = nSelect % nCount;


	*pTcsInfo = m_arCsInfo[nIndex].xRetCsInfo;

	return 0;
}

int GWMsgMan::vUdpCmdDispatch(SOCKET hSocket,TG_UDP_ADDR *pAddr,NET_PACKET_HEAD *pMsgHead,BYTE *pBuffer)
{
	int nRet = TG_ERR_FAILURE;

	int  nRetSize = sizeof(NET_PACKET_HEAD);
	char szRetBuffer[256];
	memset(szRetBuffer,0,sizeof(szRetBuffer));

	NET_PACKET_HEAD *pRetMsgHead = (NET_PACKET_HEAD*)szRetBuffer;

	pRetMsgHead->nMsgType   = pMsgHead->nMsgType + 1;
	pRetMsgHead->nFrameSize = 0;
	pRetMsgHead->nDataLen   = 0;


	char szPeerIP[128] = { 0 };
	sprintf(szPeerIP, "%s", inet_ntoa(pAddr->xAddr.sin_addr));
	int nPeerPort = ntohs(pAddr->xAddr.sin_port);

	switch( pMsgHead->nMsgType )
	{
	case ping_gw_req:
		{
			if( pMsgHead->nDataLen == sizeof(TcsPingGW) )
			{
				TcsPingGW *pTcs = (TcsPingGW*)pBuffer;

				UpdateCsInfo( pTcs,szPeerIP,nPeerPort );

				memcpy( szRetBuffer+sizeof(NET_PACKET_HEAD),pTcs->nodeid,sizeof(pTcs->nodeid) );

				pRetMsgHead->nFrameSize = 12;
				pRetMsgHead->nDataLen   = 12;

				nRetSize += 12;

				nRet = TG_ERR_SUCCESS;
			}
		}
		break;
	case get_tcs_req:
		{
			if( pRetMsgHead->nDataLen == sizeof(ReqTcsInfo) )
			{
				ReqTcsInfo *pReq = (ReqTcsInfo*)pBuffer;

				int nSelect = 0;

				for(int i=0;i<32;i++)
				{
					nSelect += pReq->LoginName[i];
				}

				RetTcsInfo *pTcsInfo = (RetTcsInfo *)(szRetBuffer + sizeof(NET_PACKET_HEAD) );

				GetCsInfo(nSelect,pTcsInfo);

				pRetMsgHead->nFrameSize = sizeof(RetTcsInfo);
				pRetMsgHead->nDataLen   = sizeof(RetTcsInfo);
				nRetSize += sizeof(RetTcsInfo);

				nRet = TG_ERR_SUCCESS;
			}
		}
		break;
	default:
		break;
	}

	
	pRetMsgHead->nErrFlag   = nRet;
	pRetMsgHead->SetCRC();

	sendto( hSocket,
		(char*)szRetBuffer,nRetSize,
		0,
		(struct sockaddr*)&pAddr->xAddr,pAddr->nAddrLen );
	

	return nRet;
}